package com.wyg.blog.controller.manage_blog;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wyg.blog.model.blog.Blog;
import com.wyg.blog.model.blog.BlogTag;
import com.wyg.blog.model.blog.Comment;
import com.wyg.blog.model.blog.MyComment;
import com.wyg.blog.service.blog.BlogService;
import com.wyg.blog.service.blog.BlogTagService;
import com.wyg.blog.service.blog.TagService;
import com.wyg.blog.service.blog.TypeService;
import com.wyg.blog.utils.JsonResult;
import com.wyg.blog.utils.UsefulConst;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.text.ParseException;
import java.util.*;

/**
 * @description:
 * @author: WYG
 * @time: 2020/7/2 22:29
 */
@RestController
@RequestMapping("/api/blog")
public class BlogController {
    private static final Logger log = LoggerFactory.getLogger(BlogController.class);

    @Autowired
    BlogService blogService;

    @Autowired
    BlogTagService blogTagService;

    @Autowired
    TagService tagService;

    @Autowired
    TypeService typeService;

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @GetMapping("/getSomeBlogs")
    @CrossOrigin
    @PreAuthorize("hasAnyRole('ADMIN','SUPER_ADMIN')")
    public JsonResult<List<Map<String,Object>>> getSomeBlogs(@RequestParam("current") Integer current, @RequestParam("size") Integer size,
                                                @RequestParam("username") String username) throws ParseException {
        Page<Blog> page = new Page<>(current,size);
        IPage<Blog> blogIPage = blogService.selectSomeBlogs(page, username);
        List<Map<String,Object>> results =  new ArrayList<>();
        List<Blog> blogs = blogIPage.getRecords();
        long MySize = blogIPage.getSize();
        long MyCurrent = blogIPage.getCurrent();
        long total = blogIPage.getTotal();
        for(int i = 0; i < blogs.size(); i++){
            Blog blog = blogs.get(i);
            String typeName = typeService.selectTypeName(blog.getType_id());
            List<Integer> tagIds = blogTagService.selectTagIdByBid(blog.getId());
            List<String> tagName = new ArrayList<>();
            for(int j = 0; j < tagIds.size(); j++){
                tagName.add(tagService.selectTagNameById(tagIds.get(j)));
            }
            Map<String,Object> result = new HashMap<>();
            result.put("id", blog.getId().toString());
            result.put("title", blog.getTitle());
            result.put("create_time", blog.getCreate_time());
            result.put("type", typeName);
            result.put("tags", tagName.toString());
            result.put("published", "" + blog.isPublished());
            result.put("total", "" + total);
            result.put("size", "" + MySize);
            result.put("current", "" + MyCurrent);
            results.add(result);
        }
        return new JsonResult<>(results,"200","博客查询成功");
    }

    @PostMapping("/publishBlog")
    @CrossOrigin
    @PreAuthorize("hasAnyRole('ADMIN','SUPER_ADMIN')")
    public JsonResult<Integer> publishBlog(@RequestBody Map<String,String> blogInfo) throws IOException {
        Blog blog = new Blog();
        blog.setId(0);
        blog.setAuthor(blogInfo.get("author"));
        blog.setCreate_time(new Date());
        blog.setTitle(blogInfo.get("title"));
        blog.setType_id(Integer.parseInt(blogInfo.get("type_id")));
        blog.setViews(0);
        blog.setLikes(0);
        blog.setFirst_picture(blogInfo.get("first_picture"));
        blog.setDescription(blogInfo.get("description"));
        if(blogInfo.get("published") == "true"){
            blog.setPublished(true);
        } else {
            blog.setPublished(false);
        }
        blog.setContent(blogInfo.get("text_content"));
        blog.setUid(Integer.parseInt(blogInfo.get("uid")));
        Integer BlogId = blogService.insertBlog(blog);

        //将博客对应的纯文本信息存入数据库中,方便后续的编辑操作
        boolean content = blogService.insertContent(BlogId, blogInfo.get("content"));

        String tagIds = blogInfo.get("tag_id");
        System.out.println(tagIds);
        String[] tagArray = tagIds.split(",");
        List<BlogTag> blogTags = new ArrayList<>();
        for(int i = 0; i < tagArray.length; i++){
            BlogTag blogTag = new BlogTag();
            blogTag.setId(0);
            blogTag.setBid(BlogId);
            blogTag.setTid(Integer.parseInt(tagArray[i]));
            blogTags.add(blogTag);
        }
        boolean res = blogTagService.insertBlogTag(blogTags);

        //将博客同时添加至elasticsearch中,以下为插入elasticsearch的代码
        IndexRequest request = new IndexRequest(UsefulConst.ELASTIC_BLOG_INDEX.getInformation());
        request.id(blog.getId().toString());
        request.timeout("3m");
        request.source(JSON.toJSONString(blog), XContentType.JSON);

        IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        log.info(indexResponse.status().toString());

        if(BlogId != null && res && content){
            return new JsonResult<>(1,"200","发布成功");
        } else {
            return new JsonResult<>(0,"701","发布失败");
        }
    }

    // 修改elasticsearch中published的状态
    @GetMapping("/changeBlogState")
    @CrossOrigin
    @PreAuthorize("hasAnyRole('ADMIN','SUPER_ADMIN')")
    public JsonResult<Integer> changeBlogState(@RequestParam("bid") Integer bid, @RequestParam("state") boolean state) throws IOException {
        boolean res = false;
        System.out.println(state);
        UpdateRequest updateRequest = new UpdateRequest(UsefulConst.ELASTIC_BLOG_INDEX.getInformation(),
                bid.toString());
        Map<String, Object> parameters = new HashMap<>();
        if(state){
            res = blogService.publishBlog(bid);
            parameters.put("published", "true");
            updateRequest.doc(parameters);
            UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
            log.info("更新信息结果:" + update.status().getStatus());
        } else {
            res = blogService.lockBlog(bid);
            parameters.put("published", "false");
            updateRequest.doc(parameters);
            UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
            log.info("更新信息结果:" + update.status().getStatus());
        }
        if (res) {
            return new JsonResult<>(1,"200","修改成功!");
        } else {
            return new JsonResult<>(0,"703","修改失败!");
        }
    }

    @PostMapping("/deleteBlog")
    @CrossOrigin
    @PreAuthorize("hasAnyRole('ADMIN','SUPER_ADMIN')")
    public JsonResult<Integer> deleteBlog(Integer id){
        boolean res = blogService.removeBlog(id);
        if (res) {
            return new JsonResult<>(1,"200","删除成功!");
        } else {
            return new JsonResult<>(0,"702","删除失败");
        }
    }


    @GetMapping("/fuzzy")
    @CrossOrigin
    @PreAuthorize("hasAnyRole('ADMIN', 'SUPER_ADMIN')")
    public JsonResult<List<Map<String, Object>>> fuzzySearch(@RequestParam("username") String username,
                                                             @RequestParam("blog") String bolg) {
        Page<Blog> page = new Page<>(1,50);
        String blogParam = "%" + bolg + "%";
        IPage<Blog> blogIPage = blogService.selectBolgByLike(page, username, blogParam);
        List<Map<String,Object>> results =  new ArrayList<>();
        List<Blog> blogs = blogIPage.getRecords();
        long MySize = blogIPage.getSize();
        long MyCurrent = blogIPage.getCurrent();
        long total = blogIPage.getTotal();
        for(int i = 0; i < blogs.size(); i++){
            Blog blog = blogs.get(i);
            String typeName = typeService.selectTypeName(blog.getType_id());
            List<Integer> tagIds = blogTagService.selectTagIdByBid(blog.getId());
            List<String> tagName = new ArrayList<>();
            for(int j = 0; j < tagIds.size(); j++){
                tagName.add(tagService.selectTagNameById(tagIds.get(j)));
            }
            Map<String,Object> result = new HashMap<>();
            result.put("id", blog.getId().toString());
            result.put("title", blog.getTitle());
            result.put("create_time", blog.getCreate_time());
            result.put("type", typeName);
            result.put("tags", tagName.toString());
            result.put("published", "" + blog.isPublished());
            result.put("total", "" + (total >= 50 ? 50 : total));
            result.put("size", "" + MySize);
            result.put("current", "" + MyCurrent);
            results.add(result);
        }
        return new JsonResult<>(results,"200","博客查询成功");
    }

    @GetMapping("/getBlogDetailById")
    @CrossOrigin
    @PreAuthorize("hasAnyRole('ADMIN', 'SUPER_ADMIN')")
    public JsonResult<Map<String, Object>> getBlogDetailById(Integer id){
        Blog blog = blogService.selectBlogById(id);
        String content = blogService.selectContent(id);
        List<Integer> tagIds = blogTagService.selectTagIdByBid(id);
        Map<String, Object> results = new HashMap<>();
        results.put("blog", blog);
        results.put("tagIds", tagIds);
        return new JsonResult<>(results, "200", "博客查询成功!");
    }

    @PostMapping("/editBlog")
    @CrossOrigin
    @PreAuthorize("hasAnyRole('ADMIN', 'SUPER_ADMIN')")
    public JsonResult<Boolean> editBlog(@RequestBody Map<String, String> updateInfo) {
        Integer BlogId = Integer.parseInt(updateInfo.get("id"));
        // 更新博客详情
        boolean renewBlog = blogService.renewBlog(BlogId, updateInfo.get("title"), Integer.parseInt(updateInfo.get("type_id")),
                updateInfo.get("description"), updateInfo.get("text_content"));
        // 更新博客文本内容
        boolean renewContent = blogService.renewContent(BlogId, updateInfo.get("content"));

        // 更新博客对应的标签
        String tagIds = updateInfo.get("tag_id");
        System.out.println(tagIds);
        String[] tagArray = tagIds.split(",");
        List<BlogTag> blogTags = new ArrayList<>();
        for(int i = 0; i < tagArray.length; i++){
            Integer tid = Integer.parseInt(tagArray[i]);
            BlogTag blogTag = new BlogTag();
            blogTag.setId(0);
            blogTag.setBid(BlogId);
            blogTag.setTid(tid);
            blogTags.add(blogTag);
        }

        boolean isInsert = false;
        if (blogTags.size() != 0) {
            boolean isDelete = blogTagService.removeBlogTagByBid(BlogId);
            if (isDelete) {
                isInsert = blogTagService.insertBlogTag(blogTags);
            }
        }

        // 根据更新过程返回结果
        if (renewContent && renewBlog && (isInsert || blogTags.size() == 0)) {
            return new JsonResult<>(true, "200", "编辑成功!");
        } else {
            return new JsonResult<>(false, "703", "编辑失败!");
        }

    }

}
